// 工具函数库(https://www.html.cn/doc/lodash/)x
import {
    isEmpty as isEmptyFunc,
    isNaN as isNaNFunc,
    isNumber as isNumberFunc,
    isUndefined as isUndefinedFunc,
    isString as isStringFunc,
    clone as cloneFunc,
    cloneDeep as cloneDeepFunc,
    throttle as throttleFunc
} from 'lodash';
import dayjs from 'dayjs';
import prenv from '../prenv';
import store from '../store';
import storage from './storage';
import request from '@/request';
import { ERROR_MESSAGE_CODE } from '@/request/const';
import { ORDER_STATUS_NAME_OPTIONS } from './const';
const manifestPath = '../manifest.json';
const manifest = import.meta.globEager('../manifest.json')[manifestPath].default;

// export const isEmpty = isEmptyFunc;
export const isNaN = isNaNFunc;
export const isNumber = isNumberFunc;
export const isUndefined = isUndefinedFunc;
export const isNotUndefined = args => !isUndefinedFunc(args);
export const clone = cloneFunc;
export const cloneDeep = cloneDeepFunc;
export const isString = isStringFunc;
export const isObject = obj => Object.prototype.toString.call(obj) === '[object Object]';

/**
 * 检查val是否为空
 * @param {*} val
 * @returns
 */
export const isEmpty = val => {
    if (isNumber(val)) {
        return false;
    }
    return isEmptyFunc(val);
};

/**
 * 检查val是否不为空，0被认为不为空，undefined/null/NaN/{}/[]都会被认为空
 * @param {*} val
 */
export const isNotEmpty = val => {
    if (isNaN(val)) {
        return false;
    }
    if (isNumber(val)) {
        return true;
    }
    return !isEmpty(val);
};

export const getVersion = () => {
    return manifest.versionName;
};

/**
 * 将val值按照format进行格式化
 * @param {*} val
 * @param {*} format
 */
export const format = (val, format = 'YYYY-MM-DD HH:mm:ss') => {
    return dayjs(val).format(format);
};

/**
 * 传入时间和当前时间对比
 * @param {*} time
 */
export const timeDiff = time => {
    const now = dayjs(new Date());
    const dateVal = dayjs(time);
    return now.diff(dateVal) > 0;
};

/**
 * 倒计时
 * @param {*} start end
 */
export const getDiffTimeInfo = (start, end) => {
    const startTimeStamp = dayjs(start).valueOf();
    const endTimeStamp = dayjs(end).valueOf();
    const millisecondDiff = endTimeStamp - startTimeStamp;
    const mistiming = millisecondDiff / 1000;
    const hours = Math.floor(mistiming / 60 / 60); // 获取小时数
    const minutes = Math.floor((mistiming / 60) % 60); // 获取秒数分钟数
    const seconds = Math.floor(mistiming % 60); // 获取秒数
    const curHours = millisecondDiff <= 0 ? '00' : hours < 10 ? `0${hours}` : hours;
    const curMinutes = millisecondDiff <= 0 ? '00' : minutes < 10 ? `0${minutes}` : minutes;
    const curSeconds = millisecondDiff <= 0 ? '00' : seconds < 10 ? `0${seconds}` : seconds;
    return {
        curHours,
        curMinutes,
        curSeconds,
        millisecondDiff
    };
};

/**
 * 倒计时- 天-时分秒
 * @param {*} start end
 */
export const getDiffDateInfo = (start, end) => {
    const startTimeStamp = dayjs(start).valueOf();
    const endTimeStamp = dayjs(end).valueOf();
    const millisecondDiff = endTimeStamp - startTimeStamp;
    const mistiming = millisecondDiff / 1000;
    const curDay = Math.floor(mistiming / (60 * 60 * 24)); // 获取天数
    const hours = Math.floor((mistiming / (60 * 60)) % 24); // 获取小时数
    const minutes = Math.floor((mistiming / 60) % 60); // 获取秒数分钟数
    const seconds = Math.floor(mistiming % 60); // 获取秒数
    const curHours = millisecondDiff <= 0 ? '00' : hours < 10 ? `0${hours}` : hours;
    const curMinutes = millisecondDiff <= 0 ? '00' : minutes < 10 ? `0${minutes}` : minutes;
    const curSeconds = millisecondDiff <= 0 ? '00' : seconds < 10 ? `0${seconds}` : seconds;
    return {
        curDay,
        curHours,
        curMinutes,
        curSeconds,
        millisecondDiff
    };
};

export const getPlatform = () => {
    // 条件编译获取uni编译平台,与后端枚举值保持一致
    // platform   1-微信小程序  2-app 3-h5 4-抖音小程序
    let platform = '';

    /* #ifdef MP-WEIXIN */
    platform = '1';
    /* #endif */

    /* #ifdef H5 */
    platform = '3';
    /* #endif */

    /* #ifdef MP-TOUTIAO */
    platform = '4';
    /* #endif */

    /* #ifdef MP-ALIPAY */
    platform = 'MP-ALIPAY';
    /* #endif */

    /* #ifdef MP-BAIDU */
    platform = 'MP-BAIDU';
    /* #endif */

    return platform;
};

/**
 * 是否为手机号
 * @param {*} mobile
 * @returns
 */
export const isMobile = mobile => {
    const phone_pattern = new RegExp('^1[3-9][0-9]{9}$', 'i');
    return phone_pattern.test(mobile);
};

/**
 * @param {*} imgName
 * @returns
 */
export const getImgOssUrl = imgName => {
    const currentEnv = store.useEnvStore().currentEnv;
    return prenv[currentEnv]['IMAGE_OSS_URL_HEADER'] + imgName;
};

/*
 * 将科学计数法的数字转为字符串
 * @param  num
 */
export const toNonExponential = num => {
    if (num == null) {
        return num;
    }
    if (typeof num == 'number') {
        var m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/);
        return num.toFixed(Math.max(0, (m[1] || '').length - m[2]));
    } else {
        return num;
    }
};
/**
 * 乘法 - js运算精度丢失问题
 * @param arg1  数1
 * @param arg2  数2
 */
export const floatMultiply = (arg1, arg2) => {
    arg1 = Number(arg1);
    arg2 = Number(arg2);
    if ((!arg1 && arg1 !== 0) || (!arg2 && arg2 !== 0)) {
        return null;
    }
    arg1 = toNonExponential(arg1);
    arg2 = toNonExponential(arg2);
    var n1, n2;
    var r1, r2; // 小数位数
    try {
        r1 = arg1.toString().split('.')[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split('.')[1].length;
    } catch (e) {
        r2 = 0;
    }
    n1 = Number(arg1.toString().replace('.', ''));
    n2 = Number(arg2.toString().replace('.', ''));
    return (n1 * n2) / Math.pow(10, r1 + r2);
};

/**
 * 除法 - js运算精度丢失问题
 * @param arg1  数1
 * @param arg2  数2
 */
export const floatDivide = (arg1, arg2) => {
    arg1 = Number(arg1);
    arg2 = Number(arg2);
    if (!arg2) {
        return null;
    }
    if (!arg1 && arg1 !== 0) {
        return null;
    } else if (arg1 === 0) {
        return 0;
    }
    arg1 = toNonExponential(arg1);
    arg2 = toNonExponential(arg2);
    var n1, n2;
    var r1, r2; // 小数位数
    try {
        r1 = arg1.toString().split('.')[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split('.')[1].length;
    } catch (e) {
        r2 = 0;
    }
    n1 = Number(arg1.toString().replace('.', ''));
    n2 = Number(arg2.toString().replace('.', ''));
    return floatMultiply(n1 / n2, Math.pow(10, r2 - r1));
};

/**
 * 将时间转为时间戳
 * @param timeStr  时间
 * @param stampNum  毫秒
 *
 */
export const getTimeStamp = (timeStr, stampNum) => {
    if (!timeStr) return Date.now();
    let t = timeStr;
    // eslint-disable-next-line no-useless-escape
    t = t > 0 ? t : t.toString().replace(/\-/g, '/');
    let times = new Date(t).getTime();
    if (typeof stampNum == 'number') {
        times += stampNum;
    }
    return times;
};

export const checkCountdow = (time, interval) => {
    return getTimeStamp(time, 60000 * interval) > new Date();
};

/**
 * 生成UUID字符串
 * @returns
 */
export const getUuid = () => {
    var s = [];
    var hexDigits = '0123456789abcdef';
    for (var i = 0; i < 32; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = '4';
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
    s[8] = s[13] = s[18] = s[23];
    var uuid = s.join('');
    return uuid;
};

/**
 * token 失效重新登陆
 * @returns
 */
export const checkLoginToken = async () => {
    return new Promise(resolve => {
        uni.login({
            success: res => {
                const loginCode = res.code;
                request('loginServ', {
                    loginCode,
                    grantType: 2,
                    // 游客登陆标识
                    userCode: storage.get('userCode') || ''
                })
                    .then(ret => {
                        const { token, expireTime, userId, openKid } = ret.data;
                        storage.set('token', token);
                        storage.set('expireTime', expireTime);
                        storage.set('openKid', openKid);
                        storage.set('userId', userId);
                        resolve(true);
                    })
                    .catch(e => {
                        // 该手机号尚未注册
                        if (e.data.code == 100410) {
                            resolve(false);
                        } else {
                            uni.showToast({
                                title: e.data.msg,
                                icon: 'none'
                            });
                            clearUserStorage();
                            resolve(false);
                        }
                    });
            }
        });
    });
};

/**
 * 检查是否有效登录态
 * @returns
 */
export const checkToken = async () => {
    return await checkTokenAsync();
};

/**
 * 无token或token过期情况下给用户重新登录
 */
export const checkTokenAsync = async () => {
    return new Promise(resolve => {
        if (
            isNotEmpty(storage.get('token')) &&
            isNotEmpty(storage.get('expireTime')) &&
            storage.get('expireTime') * 1000 - new Date() > 0
        ) {
            resolve(true);
        } else {
            uni.login({
                success: res => {
                    const loginCode = res.code;
                    request('loginServ', {
                        loginCode,
                        grantType: 2,
                        // 游客登陆标识
                        userCode: storage.get('userCode') || ''
                    })
                        .then(ret => {
                            const { token, expireTime, userId, openKid } = ret.data;
                            storage.set('token', token);
                            storage.set('expireTime', expireTime);
                            storage.set('openKid', openKid);
                            storage.set('userId', userId);
                            resolve(true);
                        })
                        .catch(e => {
                            // 该手机号尚未注册
                            if (e.data.code == 100410) {
                                resolve(false);
                            } else {
                                uni.showToast({
                                    title: e.data.msg,
                                    icon: 'none'
                                });
                                clearUserStorage();
                                resolve(false);
                            }
                        });
                }
            });
        }
    });
};

/**
 * 清除用户信息
 * @returns
 */
export const clearUserStorage = () => {
    storage.remove('token');
    storage.remove('expireTime');
    storage.remove('userId');
    storage.remove('openKid');
};

/**
 * 获取当前页面路径
 * @returns
 */
export const getCurrentPage = () => {
    const currentRoutes = getCurrentPages();
    const currentRoute = currentRoutes[currentRoutes.length - 1];
    const path = currentRoute.route;
    return path;
};

/**
 * 获取当前环境下的变量
 * @param {*} key
 * @returns
 */
export const getCurrentVar = key => {
    const currentEnv = store.useEnvStore().currentEnv;
    return prenv[currentEnv][key];
};

/**
 * 获取当前运行时的APP_ID
 * @returns APP_ID
 */
export const getAppId = () => {
    return uni.getAccountInfoSync().miniProgram.appId;
};

/**
 * 节流
 * @param   {function}  func        传入函数
 * @param   {number}    wait        表示时间窗口的间隔
 *
 * @return function
 */
export const throttle = (func, wait = 3000) => {
    return throttleFunc(func, wait, {
        leading: true,
        trailing: false
    });
};

/**
 * 倒计时
 * @param   {string}  date        YYYY-MM-DD HH:mm:ss
 *
 * @return string
 */
export const countdown = date => {
    let dateFormat = date.replace(/-/g, '/');
    let nowTime = +new Date();
    let futureTime = +new Date(dateFormat);
    let times = (futureTime - nowTime) / 1000;
    let d = parseInt(times / 60 / 60 / 24);
    let h = parseInt((times / 60 / 60) % 24);
    h = h < 10 ? '0' + h : h;
    let m = parseInt((times / 60) % 60);
    m = m < 10 ? '0' + m : m;
    let s = parseInt(times % 60);
    s = s < 10 ? '0' + s : s;
    return `${d ? `${d}天` : ''}${h}:${m}:${s}`;
};

/**
 * 关键字高亮
 * @param   {string}  content      文本
 * @param   {string}   key        关键字
 *
 * @return result Array
 */
export const getHighlightStrArray = (content, key, result) => {
    if (result == undefined) {
        result = [];
    }
    key = key.toUpperCase();
    let keyLen = key.length;
    let tmp = content.toUpperCase();
    if (tmp.length >= keyLen && keyLen > 0) {
        let index = -1;
        index = tmp.indexOf(key);
        if (index != -1) {
            let text = content.substring(0, index);
            result.push({
                color: '#33302d',
                text: text
            });
            let keyText = content.substring(index, index + keyLen);
            result.push({
                color: '#fe292b',
                text: keyText
            });
            content = content.substring(index + keyLen, content.length);
            getHighlightStrArray(content, key, result);
        } else {
            result.push({
                color: '#33302d',
                text: content
            });
        }
    } else {
        result.push({
            color: '#33302d',
            text: content
        });
    }
    return result;
};

export const checkLocationAuth = async code => {
    await uni.getSetting({
        success(res) {
            const authSetting = res.authSetting;
            if (!authSetting['scope.userLocation']) {
                uni.authorize({
                    scope: 'scope.userLocation',
                    fail() {
                        // 引导用户授权
                        uni.showModal({
                            title: '授权',
                            content: '需要获取你的位置信息',
                            success: function (res) {
                                if (res.confirm) {
                                    uni.openSetting({});
                                }
                            }
                        });
                    }
                });
            }
        }
    });
};

/**
 * 翻译订单状态Name
 * @param {string, Number} orderStatus  订单状态值
 * @param {string, Number} type  类型：0-快递发货订单，1-自提订单
 * @param {Boolean} showSubLabel  特殊类型：分销订单
 */
export const translateOrderCode = (orderStatus, type = 0, showSubLabel = false) => {
    return (
        ((ORDER_STATUS_NAME_OPTIONS[Number(showSubLabel) || 0] || [])[Number(orderStatus)] || {})[Number(type) || 0] ||
        ''
    );
};
/**
 * @param   {string}  filePath   本地文件路径
 *
 * @return result Promise.resolve
 */
export const uploadeFile = ({ filePath, timeout = 10000 }) => {
    return new Promise((resolve, reject) => {
        const currentEnv = store.useEnvStore().currentEnv;
        const url = prenv[currentEnv]['API_BASE_URL']['apigw'] + '/miniapp/file/upload';
        uni.uploadFile({
            url: url,
            filePath: filePath,
            name: 'file',
            timeout: timeout,
            header: {
                token: uni.getStorageSync('token') || '',
                'ZW-APP-ID': getAppId(),
                'ZW-SHOP-ID': uni.getStorageSync('ZW_SHOP_ID') || '',
                'ZW-TENANT-ID': uni.getStorageSync('ZW_TENANT_ID') || '',
                'ZW-CORP-ID': uni.getStorageSync('ZW_CORP_ID') || ''
            },
            formData: {},
            success: res => {
                const resFile = JSON.parse(res.data);
                resolve(resFile);
            },
            fail: error => {
                if (error.errMsg.includes('timeout')) {
                    uni.showToast({
                        title: ERROR_MESSAGE_CODE.other,
                        icon: 'none'
                    });
                }
                reject(error);
            }
        });
    });
};
